package com.hktf.corelib.utils;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.provider.MediaStore;
import android.util.Log;

import androidx.annotation.RequiresApi;


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class FileUtil {

    public static String sdcardPath = Config.ROOT_DIR;

    /**
     * 用绝对路径创建目录,请使用createDirInSdcard代替
     *
     * @param dir
     * @return
     */
    public static boolean createDir(String dir) {

        File homedir = new File(dir);

        boolean flag = false;
        if (homedir.exists()) {
            LogMds.d("FileUtil", "目录已经存在");
            return true;
        } else {
            flag = homedir.mkdirs(); // 创建目录
            if (flag)
                return true;
            else
                return false;
        }
    }

    /**
     * 在sdcard下面创建目录
     *
     * @param dir
     * @return
     */
    public static boolean createDirInSdcard(String dir) {

        if (!haveSdcard()) {
            return false;
        }
        String dirPath = sdcardPath + "/" + dir;

        File homedir = new File(dirPath);

        boolean flag = false;
        if (homedir.exists()) {
            LogMds.d("FileUtil", "目录已经存在");
            return true;
        } else {
            flag = homedir.mkdirs(); // 创建目录
            if (flag)
                return true;
            else
                return false;
        }

    }

    /**
     * 创建图片文件到指定目录,请使用saveImageInSdcard代替
     */
    public static boolean saveImage(String dir, String filename, Bitmap bitmap) {
        if (null == bitmap) {
            return false;
        }

        // 目录不存在则创建目录
        File homedir = new File(dir);
        if (!homedir.exists()) {
            if (!homedir.mkdirs()) {
                return false;
            }
        }

        File bitmapFile = new File(dir, filename);
        FileOutputStream bitmapWtriter = null;
        try {
            bitmapWtriter = new FileOutputStream(bitmapFile);
            if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bitmapWtriter)) {
                bitmapWtriter.flush();
                bitmapWtriter.close();
                return true;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 创建图片文件到sdcard
     */
    public static boolean saveImageInSdcard(String dir, String filename,
                                            Bitmap bitmap) {
        if (null == bitmap) {
            return false;
        }
        if (!haveSdcard()) {
            return false;
        }
        dir = sdcardPath + "/" + dir;

        // 目录不存在则创建目录
        File homedir = new File(dir);
        if (!homedir.exists()) {
            if (!homedir.mkdirs()) {
                return false;
            }
        }

        File bitmapFile = new File(dir, filename);
        FileOutputStream bitmapWtriter = null;
        try {
            bitmapWtriter = new FileOutputStream(bitmapFile);
            if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bitmapWtriter)) {
                bitmapWtriter.flush();
                bitmapWtriter.close();
                return true;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 根据绝对路径获取图片
     *
     * @return
     */
    public static Bitmap getImage(String path) {
        return BitmapFactory.decodeFile(path);
    }

    /**
     * 根据相对路径获取sdcard中的图片
     * @return
     */
    public static Bitmap getImageInSdcard(String path) {
        String pathName = sdcardPath + "/" + path;

        BitmapFactory.Options options = new BitmapFactory.Options();
        // 获取这个图片的宽和高
        options.inJustDecodeBounds = true; // true 则返回bm为空
        Bitmap bitmap = BitmapFactory.decodeFile(path, options); // 此时返回bm为空,
        // 只读大小,不耗内存,
        options.inSampleSize = 2;
        // 重新读入图片，注意这次要把options.inJustDecodeBounds 设为 false哦
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(pathName, options);
        if (null == bitmap)
            return null;
        return bitmap;
    }

    /**
     * 根据相对路径获取sdcard中图片的缩略图
     *
     * @param filePath 相对文件路径
     * @param height   图片显示高度 height=0时使用默认值80
     * @return
     */
    public static Bitmap getThumbnailInSdcard(String filePath, int height) {
        if (0 == height)
            height = 80;
        String path = sdcardPath + "/" + filePath;
        BitmapFactory.Options options = new BitmapFactory.Options();

        // 获取这个图片的宽和高
        options.inJustDecodeBounds = true; // true 则返回bm为空
        Bitmap bitmap = BitmapFactory.decodeFile(path, options); // 此时返回bm为空,
        // 只读大小,不耗内存,
        // 计算缩放比 节省内存
        int be = (int) (options.outHeight / (float) height);
        if (be <= 0)
            be = 1;
        options.inSampleSize = be;
        // 重新读入图片，注意这次要把options.inJustDecodeBounds 设为 false哦
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(path, options);
        if (null == bitmap)
            return null;
        return bitmap;
    }

    /**
     * 根据绝对路径获取图片的缩略图
     *
     * @param height   图片显示高度 height=0时使用默认值80
     * @return
     */
    public static Bitmap getThumbnail(String path, int height) {
        if (0 == height)
            height = 80;
        BitmapFactory.Options options = new BitmapFactory.Options();

        // 获取这个图片的宽和高
        options.inJustDecodeBounds = true; // true 则返回bm为空
        Bitmap bitmap = BitmapFactory.decodeFile(path, options); // 此时返回bm为空,
        // 只读大小,不耗内存,
        // 计算缩放比 节省内存
        int be = (int) (options.outHeight / (float) height);
        if (be <= 0)
            be = 1;
        options.inSampleSize = be;
        // 重新读入图片，注意这次要把options.inJustDecodeBounds 设为 false哦
        options.inJustDecodeBounds = false;
        bitmap = BitmapFactory.decodeFile(path, options);
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        LogMds.d("ia", w + "   " + h);
        return bitmap;
    }

    /**
     * 获取sdcard下某目录内的图片,不迭代子目录
     *
     * @param dir 相对于sdcard的目录
     * @return
     */
    public static List<String> getImagesInSdcardDir(String dir) {
        /* 设定目前所在路径 */
        List<String> it = new ArrayList<String>();
        File f = new File(sdcardPath + "/" + dir);
        File[] files = f.listFiles();

        /* 将所有文件存入ArrayList中 */
        if (null == files)
            return null;
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            if (isImage(file.getPath()))
                it.add(file.getPath());
        }
        return it;
    }

    /**
     * 获取sdcard下某目录内的图片,包括子目录
     *
     * @param dir 相对于sdcard的目录
     * @return
     */
    public static List<String> getAllImageInSdcardDir(String dir) {
        /* 设定目前所在路径 */
        List<String> it = new ArrayList<String>();
        File f = new File(sdcardPath + "/" + dir);
        File[] files = f.listFiles();

        /* 将所有文件存入ArrayList中 */
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            if (isImage(file.getPath()))
                it.add(file.getPath());
        }
        return it;
    }

    /**
     * 获取sdcard下面的所有图片
     *
     * @return
     */
    public static List<String> getAllImageInSdcard() {
        /* 设定目前所在路径 */
        List<String> it = new ArrayList<String>();
        File f = new File(sdcardPath);
        File[] files = f.listFiles();

        /* 将所有文件存入ArrayList中 */
        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            if (isImage(file.getPath()))
                it.add(file.getPath());
        }
        return it;
    }

    /**
     * 用绝对sdcard的路径删除文件
     *
     * @return
     */
    public static boolean deleteFileInSdcard(String path) {

        File file = new File(path);

        boolean flag = false;
        if (file.exists()) {
            flag = file.delete();
            if (flag) {
                LogMds.d("FileUtil", "文件删除成功");
                return true;
            } else {
                LogMds.d("FileUtil", "文件删除失败");
                return false;
            }

        } else {
            LogMds.d("FileUtil", "文件不存在");
            return false;
        }
    }


    /**
     * 删除指定文件/文件夹
     * 可以迭代删除文件夹下的子文件夹和文件
     *
     * @param path
     * @return
     */
    public static boolean deleteFiles(String path) {
        boolean isDeleted = true;
        File file = new File(path);
        if (file.isDirectory()) {
            // 如果是目录则逐级进行迭代。
            File[] files = file.listFiles();
            if (files.length > 0) {
                for (File tempFile : files) {
                    boolean tempDeleted = deleteFiles(tempFile
                            .getAbsolutePath());
                    if (!tempDeleted) {
                        // 删除失败
                        isDeleted = false;
                    } else {
                        // 删除成功，可以在此处做进一步处理，或打印日志。
                    }
                }
            }
            /*
             * 删除文件夹
             */
            boolean isDirDeleted = file.delete();
            if (!isDirDeleted) {
                isDeleted = false;
            }
        } else if (file.isFile()) {
            /*
             * 如果是文件，则直接删除
             */
            boolean isFileDeleted = file.delete();
            if (!isFileDeleted) {
                isDeleted = false;
            }
        } else {
            isDeleted = false;
        }
        return isDeleted;
    }

    private static final String FILE_MENU = "menu.xml";
    private static final String FILE_VCICONFIG = "vcicfg.xml";

    /**
     * 删除指定文件夹下的menu.xml,vciconfig.xml
     * 可以迭代删除文件夹下的子文件夹和文件
     *
     * @param path
     * @return
     */
    public static boolean deleteMenuFiles(String path) {
        boolean isDeleted = true;
        File file = new File(path);
        if (file.isDirectory()) {
            // 如果是目录则逐级进行迭代。
            File[] files = file.listFiles();
            if (files.length > 0) {
                for (File tempFile : files) {
                    boolean tempDeleted = deleteMenuFiles(tempFile
                            .getAbsolutePath());
                    if (!tempDeleted) {
                        // 删除失败
                        isDeleted = false;
                    } else {
                        // 删除成功，可以在此处做进一步处理，或打印日志。
                    }
                }
            }

        } else if (file.isFile()) {
            /*
             * 如果是nenu.xml or vciconfig.xml文件，则直接删除
             */
            /*boolean isFileDeleted = false;
            if (file.getName().equalsIgnoreCase(FILE_MENU) || file.getName().equalsIgnoreCase(FILE_VCICONFIG)) {
                isFileDeleted = file.delete();
            }*/
            boolean isFileDeleted = file.delete();

            if (!isFileDeleted) {
                isDeleted = false;
            }
        } else {
            isDeleted = false;
        }
        return isDeleted;
    }


    /**
     * 用绝对路径删除文件
     *
     * @return
     */
    public static boolean deleteFile(String path) {

        File file = new File(path);
        LogMds.e("cdz","删除path="+path);

        boolean flag = false;
        if (file.exists()) {
            flag = file.delete();
            if (flag) {
                LogMds.d("FileUtil", "文件删除成功");
                return true;
            } else {
                LogMds.d("FileUtil", "文件删除失败");
                return false;
            }

        } else {
            LogMds.d("FileUtil", "文件不存在");
            return false;
        }
    }

    /**
     * 删除文件，删除之前比较一下是否相等，相等则不删除
     *
     * @param strDestPath
     * @param strSourcePath
     */
    public static void deleteFile(String strDestPath, String strSourcePath) {
        if (!strSourcePath.equalsIgnoreCase(strDestPath))
            deleteFile(strDestPath);
    }

    /**
     * 过滤图片文件,判断传入的文件名是否是图片后缀结尾
     *
     * @param fName
     * @return
     */
    @SuppressLint("DefaultLocale")
    public static boolean isImage(String fName) {
        boolean re;

        /* 取得扩展名 */
        String end = fName
                .substring(fName.lastIndexOf(".") + 1, fName.length())
                .toLowerCase();

        /* 按扩展名的类型决定MimeType */
        if (end.equals("jpg") || end.equals("gif") || end.equals("png")
                || end.equals("jpeg") || end.equals("bmp")) {
            re = true;
        } else {
            re = false;
        }
        return re;
    }

    public static String[] getFileNames(String fileName) {
        File dir = new File(fileName);
        String[] names = dir.list();
        return names;
    }

    public static String getVersion(String diagnoseVersion) {
        int num = Integer.parseInt(diagnoseVersion);
        int one = num / 1000000;
        int two = (num % 100000) / 1000;
        int three = num % 1000;
        String version = String.format("V%d.%d.%d", one, two, three);
        return version;
    }

    /**
     * 判断是否插入SDcard
     */
    public static boolean haveSdcard() {
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED)) {
            return true;
        } else {
            return false;
        }
    }

    public static String parserErrorCode(int errorCode) {
        switch (errorCode) {
            case 1000:
                return "未知错误";
            case 1001:
                return "未注册用户";
            case 1002:
                return "非登陆用户";
            case 1003:
                return "你已经在其它地方登录了";
            case 1004:
                return "非cmwap用户";
            case 1005:
                return "错误的请求参数";
            case 1100:
                return "账号或密码错误";
            case 1101:
                return "由于你的密码过于简单，为了账户安全，请重置密码";
            case 1102:
                return "账号未注册";
            case 1150:
                return "批量查询用户数量过线";

            case 1257:
                return "对不起,TA不是你的粉丝！";
            default:
                return "未知错误";
        }
    }

    public static void CopyStream(InputStream is, OutputStream os) {
        final int buffer_size = 1024;
        try {
            byte[] bytes = new byte[buffer_size];
            for (; ; ) {
                int count = is.read(bytes, 0, buffer_size);
                if (count == -1)
                    break;
                os.write(bytes, 0, count);
            }
        } catch (Exception ex) {
        }
    }

    /*
     * 验证用户登录密码 长度为6--8位,由字母或数字组成
     */
    public static boolean isPassword(String password) {
        Pattern pattern = Pattern.compile("^[a-z0-9A-Z]{6,8}$");
        Matcher matcher = pattern.matcher(password);

        if (matcher.matches())
            return true;
        return false;
    }

    /*
     * 验证用户名是否是手机号
     */
    public static boolean isPhoneNumber(String userName) {
        Pattern pattern = Pattern
                .compile("^((13[0-9])|(15[^4,\\D])|(18[^4,\\D])|(14[5,7]))\\d{8}$");
        Matcher matcher = pattern.matcher(userName);

        if (matcher.matches())
            return true;
        return false;
    }

    /*
     * 验证注册用户是否邮箱注册
     */
    public static boolean getEmail(String line) {
        Pattern p = Pattern
                .compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
        Matcher m = p.matcher(line);
        return m.find();
    }

    /**
     * 获取文件大小
     *
     * @param length
     * @return
     */
    public static String formatFileSize(long length) {
        String result = null;
        int sub_string = 0;
        if (length >= 1073741824) {
            sub_string = String.valueOf((float) length / 1073741824).indexOf(
                    ".");
            result = ((float) length / 1073741824 + "000").substring(0,
                    sub_string + 3) + "GB";
        } else if (length >= 1048576) {
            sub_string = String.valueOf((float) length / 1048576).indexOf(".");
            result = ((float) length / 1048576 + "000").substring(0,
                    sub_string + 3) + "MB";
        } else if (length >= 1024) {
            sub_string = String.valueOf((float) length / 1024).indexOf(".");
            result = ((float) length / 1024 + "000").substring(0,
                    sub_string + 3) + "KB";
        } else if (length < 1024)
            result = Long.toString(length) + "B";
        return result;
    }

    /*
     * 获取文件夹大小
     */
    public static long getFileSize(File f) throws Exception {
        long size = 0;
        File flist[] = f.listFiles();
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSize(flist[i]);
            } else {
                size = size + flist[i].length();
            }
        }
        return size;
    }

    /*
     * 删除文件夹 param folderPath 文件夹完整绝对路径
     */
    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void deleteFolder(String folderPath) throws Exception {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    // 删除指定文件夹下所有文件
    // param path 文件夹完整绝对路径
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        if (tempList == null) {
            return true;
        }
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 讲assert下的文件拷贝到sdcard
     *
     * @return void
     * @throws IOException
     * @throws
     */
    public void copyBigDataToSD(Context context, String fileName) throws IOException {
        InputStream myInput;
        OutputStream myOutput = new FileOutputStream(fileName);
        myInput = context.getAssets().open(fileName);
        byte[] buffer = new byte[1024];
        int length = myInput.read(buffer);
        while (length > 0) {
            myOutput.write(buffer, 0, length);
            length = myInput.read(buffer);
        }

        myOutput.flush();
        myInput.close();
        myOutput.close();
    }
    /**
     * 讲assert下的文件拷贝到sdcard
     *
     * @return void
     * @throws IOException
     * @throws
     */
    public static void copyAssetFileToSD(Context context, String fileName,String destFileName) throws IOException {
        InputStream myInput;
        OutputStream myOutput = new FileOutputStream(destFileName);

        myInput = context.getAssets().open(fileName);
        byte[] buffer = new byte[1024];
        int length = myInput.read(buffer);
        while (length > 0) {
            myOutput.write(buffer, 0, length);
            length = myInput.read(buffer);
        }

        myOutput.flush();
        myInput.close();
        myOutput.close();
    }




    /**
     * @param soFile
     * @return void
     * @throws NameNotFoundException
     * @throws IOException
     * @throws FileNotFoundException
     * @throws
     */
    public static void assetToFile(Context context,
                                   String name, File soFile) throws IOException, NameNotFoundException {

        InputStream is = new FileInputStream(soFile);

        FileOutputStream fos = context.openFileOutput(name,
                Context.MODE_PRIVATE);


        byte[] buffer = new byte[8192];
        int count = 0;
        // 开始复制db文件
        while ((count = is.read(buffer)) > 0) {
            fos.write(buffer, 0, count);
        }
        fos.close();
        is.close();
    }

    /**
     * writeFileTOSDCardw
     *
     * @param content
     * @param path
     * @param fileName
     * @return File
     * @author zhangaichang
     */
    public static File writeToSdCard(String content, String path, String fileName) {
        File file = null;
        try {
            file = new File(path, fileName);
            file.mkdir();
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(content.getBytes());
            fileOutputStream.close();
        } catch (Exception e) {
        }
        return file;
    }

    /**
     * readFileFromSDCard
     *
     * @param filePath
     * @param fileName
     * @return xmlForString
     * @author zhangaichang
     */
    public static String readFromSDCard(String filePath, String fileName) throws Exception {
        File file = new File(filePath, fileName);

        InputStreamReader inputReader = null;
        BufferedReader bufferReader = null;
        StringBuffer strBuffer = null;
        try {
            InputStream inputStream = new FileInputStream(file);
            inputReader = new InputStreamReader(inputStream);
            bufferReader = new BufferedReader(inputReader);
            String line = null;
            strBuffer = new StringBuffer();
            while ((line = bufferReader.readLine()) != null) {
                strBuffer.append(line);
            }
            bufferReader.close();
        } catch (Exception e) {
            LogMds.e("readFromSDCard", "Error happened when write file:" + fileName, e);
        }
        return strBuffer.toString();
    }

    /**
     * 复制单个文件
     *
     * @param oldPath String 原文件路径 如：c:/fqf.txt
     * @param newPath String 复制后路径 如：f:/fqf.txt
     * @return boolean
     */
    public static void copyLogFile(String oldPath, String newPath) throws Exception {
        int bytesum = 0;
        int byteread = 0;
        File oldfile = new File(oldPath);
        if (oldfile.exists()) { //文件存在时
            InputStream inStream = new FileInputStream(oldPath); //读入原文件
            FileOutputStream fs = new FileOutputStream(newPath);
            byte[] buffer = new byte[1444];
            int length;
            while ((byteread = inStream.read(buffer)) != -1) {
                bytesum += byteread; //字节数 文件大小
                System.out.println(bytesum);
                fs.write(buffer, 0, byteread);
            }
            inStream.close();
        }
    }

    /**
     * 复制单个文件
     *
     * @param oldPath String 原文件路径 如：c:/fqf.txt
     * @param newPath String 复制后路径 如：f:/fqf.txt
     * @return boolean
     */
    public static void copyFile(String oldPath, String newPath) {
        try {
            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) { //文件存在时
                InputStream inStream = new FileInputStream(oldPath); //读入原文件
                FileOutputStream fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[1444];
                int length;
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread; //字节数 文件大小
                    System.out.println(bytesum);
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            System.out.println("复制单个文件操作出错");
            e.printStackTrace();

        }
    }

    private final static String DES = "DES/ECB/NoPadding";

    /**
     * Description 锟斤拷菁锟街碉拷锟斤拷屑锟斤拷锟�
     *
     * @param data
     * @param key  锟斤拷锟杰硷拷byte锟斤拷锟斤拷
     * @return
     * @throws Exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 锟斤拷锟揭伙拷锟斤拷锟斤拷锟斤拷蔚锟斤拷锟斤拷锟斤拷源
        SecureRandom sr = new SecureRandom();

        // 锟斤拷原始锟斤拷钥锟斤拷荽锟斤拷锟紻ESKeySpec锟斤拷锟斤拷
        DESKeySpec dks = new DESKeySpec(key);

        // 锟斤拷锟斤拷一锟斤拷锟斤拷钥锟斤拷锟斤拷锟斤拷然锟斤拷锟斤拷锟斤拷锟紻ESKeySpec转锟斤拷锟斤拷SecretKey锟斤拷锟斤拷
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher锟斤拷锟斤拷实锟斤拷锟斤拷杉锟斤拷懿锟斤拷锟�
        Cipher cipher = Cipher.getInstance(DES);

        // 锟斤拷锟斤拷钥锟斤拷始锟斤拷Cipher锟斤拷锟斤拷
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
        byte[] encodeCode = cipher.doFinal(data);

        //return MyBase64.encode(encodeCode).getBytes();
        return encodeCode;
    }


    /**
     * Description 锟斤拷菁锟街碉拷锟斤拷薪锟斤拷锟�
     *
     * @param data
     * @param key  锟斤拷锟杰硷拷byte锟斤拷锟斤拷
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 锟斤拷锟揭伙拷锟斤拷锟斤拷锟斤拷蔚锟斤拷锟斤拷锟斤拷源
        SecureRandom sr = new SecureRandom();

        // 锟斤拷原始锟斤拷钥锟斤拷荽锟斤拷锟紻ESKeySpec锟斤拷锟斤拷
        DESKeySpec dks = new DESKeySpec(key);

        // 锟斤拷锟斤拷一锟斤拷锟斤拷钥锟斤拷锟斤拷锟斤拷然锟斤拷锟斤拷锟斤拷锟紻ESKeySpec转锟斤拷锟斤拷SecretKey锟斤拷锟斤拷
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(dks);

        // Cipher锟斤拷锟斤拷实锟斤拷锟斤拷山锟斤拷懿锟斤拷锟�
        Cipher cipher = Cipher.getInstance(DES);

        // 锟斤拷锟斤拷钥锟斤拷始锟斤拷Cipher锟斤拷锟斤拷
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
        //byte[] decode = MyBase64.decode(String.valueOf(data));

        return cipher.doFinal(data);
    }

    public static int getMultiple8Bytes(int oldLen) {
        int newLen = 0;
        int remainder = oldLen % 8;
        if (remainder == 0) {
            newLen = oldLen;
        } else {
            newLen = oldLen + (8 - remainder);
        }
        return newLen;
    }

    /**
     * 判断文件是否存在
     *
     * @param strPath
     * @return
     */
    public static boolean FileExists(String strPath) {
        try {
            File file = new File(strPath);

            return file.exists();

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return false;
        }
    }

    // 复制文件夹
    public static void copyDirectioryNew(String sourceDir, String targetDir)
            throws IOException {
        // 新建目标目录
        (new File(targetDir)).mkdirs();
        // 获取源文件夹当前下的文件或目录
        File[] file = (new File(sourceDir)).listFiles();
        if (file == null) {
            return;
        }
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                File targetFile = new
                        File(new File(targetDir).getAbsolutePath()
                        + File.separator + file[i].getName());
                copyFileNew(sourceFile, targetFile);
            }
            if (file[i].isDirectory()) {
                // 准备复制的源文件夹
                String dir1 = sourceDir + "/" + file[i].getName();
                // 准备复制的目标文件夹
                String dir2 = targetDir + "/" + file[i].getName();
                copyDirectioryNew(dir1, dir2);
            }
        }
    }

    // 复制文件
    public static void copyFileNew(File sourceFile, File targetFile)
            throws IOException {


        // 新建文件输出流并对它进行缓冲
        OutputStream output = null;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            output = getOutPutStream(targetFile);
        } else {
            output = new FileOutputStream(targetFile);
        }
        if (output == null) {
            return;
        }
        // 新建文件输入流并对它进行缓冲
        FileInputStream input = new FileInputStream(sourceFile);
        BufferedInputStream inBuff = new BufferedInputStream(input);
        BufferedOutputStream outBuff = new BufferedOutputStream(output);

        // 缓冲数组
        byte[] b = new byte[1024 * 5];
        int len;
        while ((len = inBuff.read(b)) != -1) {
            outBuff.write(b, 0, len);
        }
        // 刷新此缓冲的输出流
        outBuff.flush();

        //关闭流
        inBuff.close();
        outBuff.close();
        output.close();
        input.close();
    }

    @RequiresApi(api = Build.VERSION_CODES.Q)
    public static OutputStream getOutPutStream(File file) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.Files.FileColumns.DISPLAY_NAME, file.getName());
        contentValues.put(MediaStore.Files.FileColumns.MIME_TYPE, "*/*");
        contentValues.put(MediaStore.Files.FileColumns.TITLE, file.getName());
        String path = file.getAbsolutePath().replace(file.getName(), "");
        path = path.replace(Environment.getExternalStorageDirectory().getAbsolutePath() + "/", "");
        contentValues.put(MediaStore.Files.FileColumns.RELATIVE_PATH, path);
        try {
            Uri insert = CommUtils.getContext().getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues);
            Log.d("cdz", "createFile: url : " + insert);
            Log.d("cdz", "path: " + path);
            OutputStream outputStream = CommUtils.getContext().getContentResolver().openOutputStream(insert);
            return outputStream;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 复制文件夹
    public static void copyDirectiory(String sourceDir, String targetDir)
            throws IOException {
        // 新建目标目录
        (new File(targetDir)).mkdirs();
        // 获取源文件夹当前下的文件或目录
        File[] file = (new File(sourceDir)).listFiles();
        if (file == null) {
            return;
        }
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 源文件
                File sourceFile = file[i];
                // 目标文件
                File targetFile = new
                        File(new File(targetDir).getAbsolutePath()
                        + File.separator + file[i].getName());
                copyFile(sourceFile, targetFile);
            }
            if (file[i].isDirectory()) {
                // 准备复制的源文件夹
                String dir1 = sourceDir + "/" + file[i].getName();
                // 准备复制的目标文件夹
                String dir2 = targetDir + "/" + file[i].getName();
                copyDirectiory(dir1, dir2);
            }
        }
    }

    // 复制文件
    public static void copyFile(File sourceFile, File targetFile)
            throws IOException {
        // 新建文件输入流并对它进行缓冲
        FileInputStream input = new FileInputStream(sourceFile);
        BufferedInputStream inBuff = new BufferedInputStream(input);

        // 新建文件输出流并对它进行缓冲
        FileOutputStream output = new FileOutputStream(targetFile);
        BufferedOutputStream outBuff = new BufferedOutputStream(output);

        // 缓冲数组
        byte[] b = new byte[1024 * 5];
        int len;
        while ((len = inBuff.read(b)) != -1) {
            outBuff.write(b, 0, len);
        }
        // 刷新此缓冲的输出流
        outBuff.flush();

        //关闭流
        inBuff.close();
        outBuff.close();
        output.close();
        input.close();
    }




    public boolean isDirExist(String dir) {
        File file = new File(dir);
        if (!file.exists())
            return false;
        return true;
    }

    public static final int SIZETYPE_B = 1;// B
    public static final int SIZETYPE_KB = 2;// KB
    public static final int SIZETYPE_MB = 3;// MB
    public static final int SIZETYPE_GB = 4;// GB

    /**
     * 获取文件指定文件的指定单位的大小
     *
     * @param filePath 文件路径
     * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB
     * @return double值的大小
     */
    public static double getFileOrFilesSize(String filePath, int sizeType) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
            LogMds.e("获取文件大小", "获取失败!");
        }
        return FormetFileSize(blockSize, sizeType);
    }

    /**
     * 调用此方法自动计算指定文件或指定文件夹的大小
     *
     * @param filePath 文件路径
     * @return 计算好的带B、KB、MB、GB的字符串
     */
    public static String getAutoFileOrFilesSize(String filePath) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
            LogMds.e("获取文件大小", "获取失败!");
        }
        return FormetFileSize(blockSize);
    }

    /**
     * 获取指定文件大小
     *
     * @return
     * @throws Exception
     */
    public static long getFile_Size(File file) throws Exception {
        FileInputStream fis = null;
        fis = new FileInputStream(file);
        long size = fis.available();
        fis.close();
        return size;
    }

    /**
     * 获取指定文件夹
     *
     * @param f
     * @return
     * @throws Exception
     */
    public static long getFileSizes(File f) throws Exception {
        long size = 0;
        File flist[] = f.listFiles();
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSizes(flist[i]);
            } else {
                size = size + getFileSize(flist[i]);
            }
        }
        return size;
    }

    /**
     * 转换文件大小
     *
     * @param fileS
     * @return
     */
    public static String FormetFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * 转换文件大小,指定转换的类型
     *
     * @param fileS
     * @param sizeType
     * @return
     */
    public static double FormetFileSize(long fileS, int sizeType) {
        DecimalFormat df = new DecimalFormat("#.00");
        double fileSizeLong = 0;
        switch (sizeType) {
            case SIZETYPE_B:
                fileSizeLong = Double.valueOf(df.format((double) fileS));
                break;
            case SIZETYPE_KB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
                break;
            case SIZETYPE_MB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
                break;
            case SIZETYPE_GB:
                fileSizeLong = Double.valueOf(df
                        .format((double) fileS / 1073741824));
                break;
            default:
                break;
        }
        return fileSizeLong;
    }

    /**
     * 获取sdcard的剩余空间
     *
     * @return
     */
    public static long getSDFreeSize() throws FileNotFoundException {
        //取得SD卡文件路径  
        String root = Config.getRootDir();
        if (root == null) {
            throw new FileNotFoundException();
        }
        File path = new File(root);
        StatFs sf = new StatFs(path.getPath());
        //获取单个数据块的大小(Byte)  
        long blockSize = sf.getBlockSize();
        //空闲的数据块的数量  
        long freeBlocks = sf.getAvailableBlocks();
        //返回SD卡空闲大小  
        //return freeBlocks * blockSize;  //单位Byte  
        //return (freeBlocks * blockSize)/1024;   //单位KB  
        return (freeBlocks * blockSize) / 1024 / 1024; //单位MB
    }

    /**
     * 根据系统时间获取图片名称
     *
     * @param end
     */
    public static String getFileNameForSystemTime(String end) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = sdf.format(new Date()) + end;
        return fileName;
    }

    public static String parseVDIAPPBINVersion(String targetPath, String tag) throws Exception {
        String version = null;
        //判断文件是否存在
        File tarfile = new File(targetPath);
        if (!tarfile.exists()) {
            throw new IllegalArgumentException("解析文件不存在！");
        }
        //解析文件 读模式
        RandomAccessFile raf = new RandomAccessFile(tarfile, "r");
        //long startIndex = Long.parseLong("Ox101E", 16);
        long startIndex = 1084;//SCR 盒子
        if ("G60+APP".equals(tag)) {
            startIndex = 4126;
        }
        //从 Ox101E 开始读取
        raf.seek(startIndex);
        byte[] bytes = new byte[20];


        try {
            int byteread = raf.read(bytes);
            if (byteread == 20) {
                for (int i = 0; i < 20; i++) {
                    bytes[i] = (byte) ~(bytes[i] - 2);
                }
                version = new String(bytes);
                String[] split = version.split("_V");
                String[] split2 = split[1].split(" ");
                String tempVersion = split2[0];
                String[] array = tempVersion.split("\\.");
                if (array.length == 3) {
                    String frist = String
                            .format("%03d", Integer.parseInt(array[0]));
                    String second = String.format("%03d",
                            Integer.parseInt(array[1]));
                    String last = array[2];
                    if (array[2].contains("T")) {
                        String[] split3 = array[2].split("T");
                        last = split3[0];
                    }
                    last = String.format("%03d", Integer.parseInt(last));
                    version = frist + second + last;
                }
            }
        } catch (Exception e) {
            throw e;
        }
        return version;
    }


    /**
     * 解压到temp 目录
     *
     * @param srcPathString
     * @param tempNewPath
     * @return
     */
    public static boolean unzipTempFile(String srcPathString, String tempNewPath) {

        return true;
    }

    public static boolean deleteFile(File file, DeleteFileCallback callback) {
        if (file == null || !file.exists()) {
            return false;
        }
        boolean flag = true;
        if (file.isDirectory()) {
            try {
                delAllFile(file.getAbsolutePath(), callback);
                flag = file.delete();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            flag = deleteFile(file.getAbsolutePath());
            if (callback != null) {
                callback.percentage("100%");
                callback.progress(1, 1);
            }
        }
        if (callback != null) {
            if (flag) {
                callback.onSuccess();
            } else {
                callback.onFail();
            }
        }
        return flag;
    }

    /**
     * @param path
     * @param callback
     * @return
     */
    // param path 文件夹完整绝对路径 只清空文件夹
    public static boolean delAllFile(String path, DeleteFileCallback callback) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            if (callback != null) {
                callback.onFail();
            }
            return flag;
        }
        if (!file.isDirectory()) {
            if (callback != null) {
                callback.onFail();
            }
            return flag;
        }
        String[] tempList = file.list();
        if (tempList == null) {
            if (callback != null) {
                callback.onSuccess();
            }
            return true;
        }
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (callback != null) {
                callback.progress(tempList.length, i + 1);
                callback.percentage(getPercent(i + 1, tempList.length));
            }
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        //        delFolder(path);// 再删除空文件夹
        LogMds.e("cdz", "flag =" + flag);
        if (callback != null) {
            callback.onSuccess();
        }
        return flag;
    }

    public static String getPercent(int x, int y) {
        String baifenbi = "";//接受百分比的值
        double baiy = x * 1.0;
        double baiz = y * 1.0;
        double fen = baiy / baiz;
        //NumberFormat nf   =   NumberFormat.getPercentInstance();     注释掉的也是一种方法
        //nf.setMinimumFractionDigits( 2 );        保留到小数点后几位
        DecimalFormat df1 = new DecimalFormat("##%");    //##.00%   百分比格式，后面不足2位的用0补齐
        //baifenbi=nf.format(fen);

        baifenbi = df1.format(fen);

        if (".00%".equals(baifenbi)) {
            baifenbi = "0%";
        }
        if ("100.00%".equals(baifenbi)) {
            baifenbi = "100%";
        }
        if (baifenbi.endsWith(".00%")) {
            baifenbi = baifenbi.substring(0, baifenbi.length() - 4) + "%";
        } //if去0

        return baifenbi;
    }

    public static interface DeleteFileCallback {
        void onFail();

        void progress(int all, int current);

        void percentage(String percentage);

        void onSuccess();
    }


    public static String UnicodeByteToStr(byte[] bBuf) {
//        return new String(bBuf, StandardCharsets.UTF_16LE); // 这种不会处理字符串结束符 \0
        StringBuffer result = new StringBuffer();
        Character ch = 0;
        for (int i = 0; i < bBuf.length; i += 2) {
            if (bBuf[i + 1] == 0) {
                ch = (char) bBuf[i];
            } else {
                ch = (char) ((bBuf[i] << 8) & 0xFF00 | bBuf[i + 1]);
            }

            if (ch == 0) { // 字符串结束符 \0
                break;
            }
            result.append(ch);
        }
        return result.toString();
    }

    public static String findFiles(String path) {
        String filePaths = "";
        //遍历解压后的所有文件
        File[] files = new File(path).listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    filePaths += findFiles(file.getAbsolutePath());
                } else {
                    filePaths += file.getAbsolutePath() + ";";
                }
            }
            // TODO: 2021/5/25 去除最后一个分号
            if (filePaths.endsWith(";")) {
                filePaths = filePaths.substring(0, filePaths.length() - 1);
            }
        }
        return filePaths;
    }
}
